package com.atguigu.demo1;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *  * 三个售票员    卖出      50张票
 *  * 如何编写企业级需要的工程化代码？ 多对1 多个线程操作同一个资源类
 *  JUC口诀
 *  OOP--面向对象编程
 *   1 你的需求是什么？空调制冷，点一下降低一个温度
 *
 *   2 你描述的需求我将它用一个方法搞定，告诉我，java一切皆对象
 *
 *   3 对象 = Field + method
 *
 *   4 方法  封装进入具体对象，这个对象就是被我们操作的资源类
 *
 * 1 在高内聚低耦合前提下，线程  操作  资源类
 *
 */
//资源类 = Field + method
class CountTicket{
    public int ticket = 50;

    //独占锁+可重入锁+公平(true)|默认非公平锁(false)

    Lock lock = new ReentrantLock(true);
    public void sale() {
        lock.lock();
        try {
            if (ticket > 0){
                System.out.println("lock.tryLock() = " + lock.tryLock());
                System.out.println(Thread.currentThread().getName()+ "正在卖第" + ticket-- + "票,还剩余"+ ticket +"张票");
            }
        } finally {
            lock.unlock();
        }
    }

    /*public synchronized void sale()
    {
        if(ticket > 0)
        {
            System.out.println(Thread.currentThread().getName()+"\t"+"卖出第: "+(ticket--)+"\t还剩下： "+ticket);
        }
    }*/
}

public class SaleTicket {
    public static void main(String[] args) {
        CountTicket t = new CountTicket();
        /*new Thread(new Runnable() {
            @Override
            public void run() {
                while (t.ticket > 0){
//                for (int i = 0; i < 51; i++) {
                    t.sale();
                }
            }
        },"售票员1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (t.ticket > 0){
//                for (int i = 0; i < 51; i++) {
                    t.sale();
                }
            }
        },"售票员2").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (t.ticket > 0){
//                for (int i = 0; i < 51; i++) {
                    t.sale();
                }
            }
        },"售票员3").start();*/

        //lambda表达式
        new Thread(() -> {while (t.ticket > 0) t.sale();},"A").start();
        new Thread(() -> {while (t.ticket > 0) t.sale();},"B").start();
        new Thread(() -> {while (t.ticket > 0) t.sale();},"C").start();

    }
}
